package lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : wenchao.long
 * @date : Created in 2024-03-22 下午 1:59 周五
 * @description :
 */
public class LockSupportDemo {

	static final Object objectLock = new Object();

	static final Lock lock = new ReentrantLock();

	static final Condition condition = lock.newCondition();

	public static void main(String[] args) {

		Thread thread = new Thread(() -> {
			System.out.println(Thread.currentThread().getName() + "\t" + "进来了");
			// 这里就被阻塞了 等待放行
			LockSupport.park();
			System.out.println(Thread.currentThread().getName() + "\t" + "被唤醒");
		}, "A");

		thread.start();

		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}

		new Thread(() -> {
			LockSupport.unpark(thread);
			System.out.println(Thread.currentThread().getName() + "\t" + "通知");
		}, "B").start();

	}

	private static void lockAwait() {
		new Thread(() -> {
			lock.lock();
			System.out.println(Thread.currentThread().getName() + "\t" + "进来了");
			try {
				condition.await();
			} catch (InterruptedException e) {
				lock.unlock();
				System.out.println(e.getMessage());
			}
			System.out.println(Thread.currentThread().getName() + "\t" + "被唤醒");
		}, "A").start();

		new Thread(() -> {
			lock.lock();
			condition.signal();
			System.out.println(Thread.currentThread().getName() + "\t" + "通知");
			lock.unlock();
		}, "B").start();
	}

	private static void synchronizedWait() {
		new Thread(() -> {
			synchronized (objectLock) {
				System.out.println(Thread.currentThread().getName() + "\t" + "进来了");
				try {
					objectLock.wait();
				} catch (InterruptedException e) {
					System.out.println(e.getMessage());
				}
				System.out.println(Thread.currentThread().getName() + "\t" + "被唤醒");
			}
		}, "A").start();

		new Thread(() -> {
			synchronized (objectLock) {
				objectLock.notify();
				System.out.println(Thread.currentThread().getName() + "\t" + "通知");
			}
		}, "B").start();
	}


}
